package com.wc5818.wxapi;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.Buffer;
import java.util.HashMap;
import java.util.Map;
import sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Response;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.math.ec.ECCurve.Config;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.annotation.ApplicationScope;

import com.wc5818.common.HttpXmlClient;
import com.wc5818.wxapi.bean.ToKenBean;
import com.wc5818.wxapi.bean.WxaCodeBean;

import com.alibaba.fastjson.JSON;



import com.wc5818.common.ConvertUtil;
/***
 * 
 * @author yqb 小程序接口 微信小程序封装接口
 * 
 */

@RestController
@RequestMapping("/wxminapp/api")
public class WxMinAppSDK {
	
	 
	/**
	 * 微信小程序appkey
	 */
	private final static String appKey = "wx7d8a4d35863596a0";
	/****
	 * 微信小程序 AppSecret
	 * 
	 * 
	 */
	private final static String appSecret = "fcccc7b882d88683765feec77de4e139";

	/****
	 * 构造函数
	 */
	public WxMinAppSDK() {

	}

	@RequestMapping("getwxajson")
	public WxaCodeBean getwxajson() {

		RestTemplate rt = new RestTemplate();

		ToKenBean fm = rt.getForObject(
				"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appKey+"&secret="+appSecret,
				ToKenBean.class);

		System.out.println(fm.getAccess_token());
//		 MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();        
//		 map.add("path","pages/register/register");
//		 map.add("width", "430");
//		 map.add("access_token", fm.getAccess_token());
//		 
//		
//		System.out.print(map);

		WxaCodeBean wx = new WxaCodeBean();
		wx.setAccess_token(fm.getAccess_token());
		wx.setPath("pages/register/register");
		wx.setWidth("430");

		return wx;

	}
	
	 
	
	/***
	 * https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
	 * getwxacodeunlimit 函数支持 扫码传递参数 获取小程序码Buffer
	 * 
	 * @param code
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "getWxMinCodeImageBuffer", method = RequestMethod.GET)
	public Object getWxMinCodeImageBuffer(@RequestParam("code") String code,HttpServletResponse response) throws Exception {

        ConvertUtil conver = new ConvertUtil();
		RestTemplate rt = new RestTemplate();
		WxaCodeBean wxa = getwxajson();
		Map<String, Object> params = new HashMap<String, Object>();
		
		
		//{"page":"pages/index/index","width":230,"scene":"accountID=100010"}

		params.put("page", "pages/register/register");
		params.put("width", "430"); 
		params.put("scene","code=" + code);
		
		
		byte[] byteArray = null;
		
		ResponseEntity<byte[]> entity = rt.postForEntity("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + wxa.getAccess_token(),JSON.toJSONString(params),byte[].class);
		byteArray = entity.getBody();
		
		response.setContentType("image/jpeg");
        response.setCharacterEncoding("UTF-8");
        OutputStream outputSream = response.getOutputStream();
        InputStream in = new ByteArrayInputStream(byteArray);
        
        // 加水印
        BufferedImage bufImg = new BufferedImage(460, 460, BufferedImage.TYPE_INT_RGB);
        Image srcImg = ImageIO.read(in);
        Graphics2D g = bufImg.createGraphics();
      
        
        g.setColor(Color.WHITE);//设置笔刷白色
		g.fillRect(0,0,460,460);//填充整个屏幕  
		g.setColor(Color.BLACK); //设置笔刷
		g.drawImage(srcImg, 15, 0, 430, 430, null);
        
        //Font mf = new Font(String 字体，int 风格，int 字号);
        Font font = new Font("宋体",Font.BOLD,20);
        g.setFont(font);
        g.drawString(code, 160, 450);  //画出水印
        
        InputStream in1 = new  ByteArrayInputStream(conver.imageToBytes(bufImg));
        
        int len = 0;
        byte[] buf = new byte[1024];
        while ((len = in1.read(buf, 0, 1024)) != -1) {
            outputSream.write(buf, 0, len);
        }
        
        
        
        /*** 没有加上水印的名字
        int len = 0;
        byte[] buf = new byte[1024];
        while ((len = in.read(buf, 0, 1024)) != -1) {
            outputSream.write(buf, 0, len);
        }
        **/
        
        
        outputSream.close();
		return null;
	}
	
	
	/***
	 * 保存图片
	 * @param imagePath
	 * @param byteArray
	 */
	private void generateLocalPic(String imagePath, byte[] byteArray) {
		if (StringUtils.isNotBlank(imagePath) && null != byteArray) {
			try {
				File file = new File(imagePath);
				if (!file.getParentFile().exists()) {
					file.getParentFile().mkdirs();
				}
				FileOutputStream out = new FileOutputStream(imagePath);
				out.write(byteArray);
				out.flush();
				out.close();
			} catch (Exception e) {
				 System.out.println(e.getMessage());
			}
		}
	}

	 
	

	/****
	 * 获取小程序码带参数的二维码 code 参数生成
	 * 
	 * @return
	 * @throws IOException 
	 */
    
	@RequestMapping(value = "getWxMinCode", method = RequestMethod.GET)
	public Object getWxMinCode(@RequestParam("code") String code) throws IOException {

	 

		WxaCodeBean wxa = getwxajson();
		System.out.print("out:" + wxa.getAccess_token());
		
		 

		return this.getWxQrcode(wxa.getAccess_token(),code,430);

	}
	
	/****
	 * 获取小程序码带参数的二维码 code 参数生成jpg
	 * 不能用
	 * @return
	 * @throws IOException 
	 */
    
	@RequestMapping(value = "getWxMinCodeImage", method = RequestMethod.GET,produces=MediaType.IMAGE_PNG_VALUE)
	@ResponseBody
	public Object getWxMinCodeImage(@RequestParam("code") String code) throws IOException {

		 

		WxaCodeBean wxa = getwxajson();
	    
		
		return "data:image/png;base64," + this.getWxQrcode(wxa.getAccess_token(),code,430);
        
	}

	/**
	 * 获取小程序码
	 */
	@SuppressWarnings("restriction")
	public String getWxQrcode(String access_token,  String code,Integer width) {
	        String qrcodeUrl = "https://api.weixin.qq.com/wxa/getwxacode";  // 获取小程序码的接口头部
		String url = qrcodeUrl+"?access_token="+access_token;  // 拼接完整的URl
		 
		
		String param = "{\"path\":\"pages/register/register?code="+code+"\",\"width\":\""+width+"\"}";
		
	    // 使用 RestTemplate 出现的问题，用该类代码会更简洁
		// rest debugger发过来的content-type为application/json，而jq的多了charset=utf-8
		// Could not read document: Invalid UTF-8 middle byte 0xff
		/*JSONObject jsonObject = 
				restTemplate.postForObject(url, param, JSONObject.class);
		System.out.println(jsonObject.toJSONString());*/
		
		HttpURLConnection conn = null;
		BufferedReader bufferedReader = null;
		PrintWriter out = null;
		InputStream in = null;
		ByteArrayOutputStream bos = null;
		String base64String = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			conn = (HttpURLConnection) realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("Accept-Charset", "UTF-8");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 超时设置,防止 网络异常的情况下,可能会导致程序僵死而不继续往下执行
			conn.setConnectTimeout(3000);
			conn.setReadTimeout(3000);
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			
			in = conn.getInputStream();  // 得到图片的二进制内容
			int leng = in.available();  // 获取二进制流的长度，该方法不准确
			if(leng < 1000){  // 出现错误时，获取字符长度就一百不到，图片的话有几万的长度
				// 定义BufferedReader输入流来读取URL的响应
				bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
				String line;
				String result = "";
				while ((line = bufferedReader.readLine()) != null) {
					result += line;
				} 
				// 清空 access_token 缓存
				 
				return result;
			}
			
			// 修改图片的分辨率,分辨率太大打印纸不够大
			//BufferedInputStream in2 = new BufferedInputStream(conn.getInputStream());
			// 将文件二进制流修改为图片流
			Image srcImg = ImageIO.read(in);
			// 构建图片流
			BufferedImage buffImg = new BufferedImage(width, width, BufferedImage.TYPE_INT_RGB);
			//绘制改变尺寸后的图
			buffImg.getGraphics().drawImage(srcImg.getScaledInstance(width, width, Image.SCALE_SMOOTH), 0, 0, null);
			// 将图片流修改为文件二进制流
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			ImageIO.write(buffImg, "png", os);
			in = new ByteArrayInputStream(os.toByteArray());
			// 刷新，将重置为类似于首次创建时的状态
			buffImg.flush();
			srcImg.flush();
			// 设null是告诉jvm此资源可以回收
			buffImg = null;  // 该io流不存在关闭函数
			srcImg = null;  // 该io流不存在关闭函数
			os.close();
			
			bos = new ByteArrayOutputStream();
			byte[] b1 = new byte[1024];
			int len = -1;
			while((len = in.read(b1)) != -1) {
				bos.write(b1, 0, len);
			}
			byte[] fileByte = bos.toByteArray();  // 转换为字节数组，方便转换成base64编码
			
			//BASE64Encoder encoder = new BASE64Encoder();   // import sun.misc.BASE64Encoder;  该类包为内部专用以后可能会删除，sun公司
			// 对字节数组转换成Base64字符串
			//base64String = encoder.encode(fileByte);
			
			base64String = Base64.encodeBase64String(fileByte);  // import org.apache.commons.codec.binary.Base64;
		} catch (Exception e) {
			
		}
		//使用finally块来关闭输出流、输入流
		finally{
			try {
				if(bufferedReader != null){
					bufferedReader.close();
				}
				if(out!=null){
					out.close();
				}
				if(in!=null){
					in.close();
				}
				if(bos != null){
					bos.close();
				}
				if(conn !=null){
					conn.disconnect();
					conn = null;
				}
				//让系统回收资源，但不一定是回收刚才设成null的资源，可能是回收其他没用的资源。
				System.gc();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return base64String;  // 将base64格式的图片发送到前端
	}
	
	 
	


}
